package com.novatec.mvc.servicio.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.novatec.beans.Cajas;
import com.novatec.beans.ContratoBean;
import com.novatec.beans.Productos;
import com.novatec.dao.ContratosDAO;
import com.novatec.dao.SolicitudesDAO;
import com.novatec.mvc.modelo.ClienteItem;
import com.novatec.mvc.modelo.ContratoItem;
import com.novatec.mvc.servicio.SolicitudesService;
import com.novatec.util.Constantes;
import com.novatec.util.NovatecUtil;

@SuppressWarnings("deprecation")
@Service
public class SolicitudesServiceImpl implements SolicitudesService {

	private Logger log = Logger.getLogger(this.getClass());
	
	@Autowired
	private SolicitudesDAO solDAO;
	@Autowired
	private ContratosDAO contratoDAO;

	@Override
	public List<Productos> recuperarProductosXContrato(Long idContrato) {

		ArrayList<Productos> listaProductos = new ArrayList<Productos>();
		List listaModelosCajas = solDAO.recuperarTiposCajas(idContrato);

		// este debe de ser el primer saldo del primero de la lista

		// Cajas caja = (Cajas) listaModelosCajas.get(0);

		// llamar a select DAO en tabla tipoCajas

		for (int i = 0; i < listaModelosCajas.size(); i++) {

			Productos prod = new Productos();

			Cajas caja = (Cajas) listaModelosCajas.get(i);

			List listaCajaIndividual = new ArrayList();

			listaCajaIndividual.add(caja);
			prod.setValoresSeleccionables(listaCajaIndividual);
			prod.setIdComboBox("modeloCajas" + i);
			prod.setTotalModelosCajas(String.valueOf(listaModelosCajas.size()));

			prod.setSaldoDisponible(String.valueOf(caja.getSaldoDisponible()));

			prod.setIdInputNroCajas("nroCajas" + i);
			prod.setIdInputSaldo("saldoDisponible" + i);
			prod.setCajasSeleccionadas("0");
			prod.setSaldoContable(String.valueOf(caja.getSaldoContable()));
			prod.setHiddenSaldoContable("saldoContable"+i);
			prod.setHiddenSaldoCliente("saldoCliente"+i);
			prod.setSaldoCliente(String.valueOf(caja.getSaldoCliente()));
			listaProductos.add(prod);
		}

		return listaProductos;
	}

	@Override
	public Long generarNroOrden() {
		// TODO Auto-generated method stub

		GregorianCalendar gregCal = new GregorianCalendar();
		Calendar ahoraCal = Calendar.getInstance();

		String anho = String.valueOf(ahoraCal.get(Calendar.YEAR));
		String mes = NovatecUtil.concatenarCeroFormatoFecha(String
				.valueOf(ahoraCal.get(Calendar.MONTH)));
		String dia = NovatecUtil.concatenarCeroFormatoFecha(String
				.valueOf(ahoraCal.get(Calendar.DATE)));
		String hora = NovatecUtil.concatenarCeroFormatoFecha(String
				.valueOf(ahoraCal.get(Calendar.HOUR_OF_DAY)));
		String minutos = NovatecUtil.concatenarCeroFormatoFecha(String
				.valueOf(ahoraCal.get(Calendar.MINUTE)));
		String segundos = NovatecUtil.concatenarCeroFormatoFecha(String
				.valueOf(ahoraCal.get(Calendar.SECOND)));

		// falta ajustar el tema del correlativo
		// int correlativo =

		Long nrOrden = new Long(anho + mes + dia + hora + minutos + segundos);

		return nrOrden;
	}

	@Override
	public void guardarSolicitud() {
		// TODO Auto-generated method stub

	}

	@Override
	public String obtenerDireccion() {
		// TODO Auto-generated method stub
		// llamar al DAO que trae la direccion

		// pseudo MOCK
		String direccion = "Av. Faisanes 181 Chorrillos";

		return direccion;

	}

	@Override
	public String obtenerTipoEnvio(Long idCliente) {
		// TODO Auto-generated method stub
		return String.valueOf(idCliente);
	}

	@Override
	public Long obtenerContrato(Long idCliente) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ContratoBean recuperarContratoCliente(Long IdCliente, Integer vigente) {
		// TODO Auto-generated method stub

		return solDAO.recuperarContratoXCLiente(IdCliente, vigente);
	}

	@Override
	public ClienteItem obtenerIdClienteDesdeContrato(Long idContrato) {
		// TODO Auto-generated method stub
		return solDAO.recuperarCLienteXContrato(idContrato);
	}

	@Override
	public List<Productos> recuperarProductosDetSolicitud(Long idContrato,
			Long nroOrden) {
		// TODO Auto-generated method stub
		List lista = solDAO.recuperarTiposCajasEnDetSolicitud(idContrato,
				nroOrden);
		ArrayList<Productos> listaProductos = new ArrayList<Productos>();
		for (int i = 0; i < lista.size(); i++) {

			Productos prod = new Productos();

			Cajas caja = (Cajas) lista.get(i);

			List listaCajaIndividual = new ArrayList();

			listaCajaIndividual.add(caja);
			
			prod.setValoresSeleccionables(listaCajaIndividual);
			prod.setIdComboBox("modeloCajas" + i);
			prod.setTotalModelosCajas(String.valueOf(lista.size()));
			prod.setSaldoDisponible(String.valueOf(caja.getSaldoCliente()));
			prod.setIdInputNroCajas("nroCajas" + i);
			prod.setIdInputSaldo("saldoDisponible" + i);
			prod.setCajasSeleccionadas( String.valueOf(caja.getCantidadSeleccionada()) );
			prod.setResponsable( caja.getResponsable() );
			prod.setReposicion(caja.getReposicion());
			prod.setDirenvio(caja.getDirenvio());
			prod.setRefenvio(caja.getRefenvio());
			
			listaProductos.add(prod);

		}

		return listaProductos;
	}

	@Override
	public Cajas obtenerReposicionSolicitudDevolucion(Long orden, Long idCliente) {
		// TODO Auto-generated method stub
		return solDAO.recuperarReposicionEnSolicitud(orden, idCliente);
	}
	
	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public void actualizarEstado(Long[] nroOrden, Long[] estado, String[] transaccion, Boolean[]ischange, String[] guia){
		
		for (int i = 0, total = nroOrden.length; i < total; i++) {
			/*if (/*!ischange[i] ||estado[i]==solDAO.recuperarIdEstadoSolicitudByNroOrden(nroOrden[i])) 
			{
				continue;
			}else if(guia[i] == solDAO.recuperarGuiaByNroOrden(nroOrden[i]).getGuia()){
					
				}
				if (guia[i] == solDAO.recuperarGuiaByNroOrden(nroOrden[i]).getGuia()){
					continue;
				}
			}*/
			log.debug("Guia actual: " + solDAO.recuperarGuiaByNroOrden(nroOrden[i]).getGuia());
			log.debug("Guia nueva: " + guia[i]);
			log.debug("Estado actual: " + solDAO.recuperarIdEstadoSolicitudByNroOrden(nroOrden[i]));
			log.debug("Estado nueva: " + estado[i]);
			log.debug("-------");
			log.debug("Guia modificada:" + (!guia[i].equals(solDAO.recuperarGuiaByNroOrden(nroOrden[i]).getGuia())));
			log.debug("Estado modificado:" + (estado[i] != solDAO.recuperarIdEstadoSolicitudByNroOrden(nroOrden[i])));			
			
			if(estado[i]!=solDAO.recuperarIdEstadoSolicitudByNroOrden(nroOrden[i]) || !guia[i].equals(solDAO.recuperarGuiaByNroOrden(nroOrden[i]).getGuia()) ){
				
				if(!guia[i].equals(solDAO.recuperarGuiaByNroOrden(nroOrden[i]).getGuia()) && estado[i]==solDAO.recuperarIdEstadoSolicitudByNroOrden(nroOrden[i])){
					solDAO.actualizarEstado(nroOrden[i], estado[i], guia[i]);
				}else{
					String tipoSaldo= Constantes.TIPOSALDO_DISPONIBLE;
					char accion=' ';
					//fvill 11-04-2012 ini
					if((Constantes.TIPOSOLICITUD_PEDIDO.equals(transaccion[i]))){
						accion= Constantes.RESTA_SALDO;
					} 
					if((Constantes.TIPOSOLICITUD_DEVOLUCION.equals(transaccion[i]))){
						accion= Constantes.SUMA_SALDO;
					}
					//char accion= Constantes.SUMA_SALDO;
					//fvill 11-04-2012 ini
					
					Integer numCajas= solDAO.recuperarNumCajasByNroOrden(nroOrden[i]);
					if (Constantes.TIPOSOLICITUD_PEDIDO.equals(transaccion[i])){
						
						//fvilla 11-04-2012 ini
						if(estado[i]==Constantes.ESTADOSOLICITUD_ENTREGADO){ 
							tipoSaldo= Constantes.TIPOSALDO_CLIENTE;
							accion= Constantes.SUMA_SALDO; //<--- para sume el stock en cliente cuando un pedido es entregado
						}
						
						if(estado[i]==Constantes.ESTADOSOLICITUD_INVALIDADO){
							accion= Constantes.SUMA_SALDO; // xq va a devolver saldo px

						}
						
						//fvilla 11-04-2012 fin						
						
					}else if(Constantes.TIPOSOLICITUD_DEVOLUCION.equals(transaccion[i])){
						if(estado[i]==Constantes.ESTADOSOLICITUD_ENTREGADO){
							accion= Constantes.RESTA_SALDO;
							//fvilla 12-04-2012 ini
								//tipoSaldo= Constantes.TIPOSALDO_CLIENTE;
								tipoSaldo= Constantes.TIPOSALDO_PORDEVOLVER; // disminuye el saldo por devolver
							//fvilla 12-04-2012 ini
						}else if(estado[i]==Constantes.ESTADOSOLICITUD_ENLAVADO){
							//fvilla 12-04-2012 ini
								//accion= Constantes.RESTA_SALDO;
								accion= Constantes.SUMA_SALDO; // aumenta el saldo en stock en lavado
							//fvilla 12-04-2012 fin
							tipoSaldo= Constantes.TIPOSALDO_ENLAVADO;
						}else if(estado[i]==Constantes.ESTADOSOLICITUD_ENALMACEN){
							// fvilla 12-04-2012 ini
								//contratoDAO.actualizarSaldo(nroOrden[i], numCajas, accion, tipoSaldo); //se comento xq solo debe reducir el saldo en lavado
							// fvilla 12-04-2012 fin							
							accion= Constantes.RESTA_SALDO;
							tipoSaldo= Constantes.TIPOSALDO_ENLAVADO;
						}else if(estado[i]==Constantes.ESTADOSOLICITUD_INVALIDADO){
							// fvilla 12-04-2012 ini
							// se comento las 3 lineas de abajo xq cuando una devolucion pasa a invalidada no actualiza nada (si viene del estado registrado)
								//contratoDAO.actualizarSaldo(nroOrden[i], numCajas, accion, tipoSaldo);
								//accion= Constantes.RESTA_SALDO;
								//tipoSaldo= Constantes.TIPOSALDO_PORDEVOLVER;
							
							if(solDAO.recuperarIdEstadoSolicitudByNroOrden(nroOrden[i])==1){ // devolucion registrada
								numCajas=0; // para q no actulize el saldo al final del presente if
							}
							
							if(solDAO.recuperarIdEstadoSolicitudByNroOrden(nroOrden[i])==2){ // devolucion atendida

								accion= Constantes.RESTA_SALDO;
								tipoSaldo= Constantes.TIPOSALDO_PORDEVOLVER;
								contratoDAO.actualizarSaldo(nroOrden[i], numCajas, accion, tipoSaldo);
								tipoSaldo= Constantes.TIPOSALDO_DISPONIBLE;
								contratoDAO.actualizarSaldo(nroOrden[i], numCajas, accion, tipoSaldo);
								
								accion= Constantes.SUMA_SALDO;
								tipoSaldo= Constantes.TIPOSALDO_CLIENTE;
							}
							
							// fvilla 12-04-2012 fin
							
						}
						//fvilla 12-04-2012 ini 
						else if(estado[i]==Constantes.ESTADOSOLICITUD_ATENDIDO){
							// disminuye el saldo en el cliente
							accion= Constantes.RESTA_SALDO;
							tipoSaldo= Constantes.TIPOSALDO_CLIENTE;
							contratoDAO.actualizarSaldo(nroOrden[i], numCajas, accion, tipoSaldo);
							// aumenta el saldo por devolver
							accion= Constantes.SUMA_SALDO;
							tipoSaldo= Constantes.TIPOSALDO_PORDEVOLVER;
							contratoDAO.actualizarSaldo(nroOrden[i], numCajas, accion, tipoSaldo);
							//deja seteado tipo saldo para que actualize el saldo disponible
							tipoSaldo= Constantes.TIPOSALDO_DISPONIBLE;
						}
						//fvilla 12-04-2012 fin 						
					}
					
					//fvilla 12-04-2012 ini
					// se agrego el if para evitar actualizaciones triviales
					if(numCajas>0){
						contratoDAO.actualizarSaldo(nroOrden[i], numCajas, accion, tipoSaldo);						
					}
					//fvilla 12-04-2012 fin
					
					
					solDAO.actualizarEstado(nroOrden[i], estado[i], guia[i]);
				}	
			}else{
				log.debug("No actualiza esta orden: " + nroOrden[i].toString());
				continue;
			}
			
				
		}
				
	}
}